77
<template>
  <div>
    <el-card>
      <el-scrollbar :always="false" :min-size="1">
        <div class="scrollbar-flex-content">
          <el-tag
            class="scrollbar-demo-item"
            v-for="(item, index) in tagCl.tagsStore.menuTags"
            :key="item.path"
            :closable="item.name !== '首页'"
            :disable-transitions="false"
            :effect="router.currentRoute.value.fullPath === item.path ? 'dark' : 'plain'"
            size="small"
            @click="handleClick(item)"
            @close="handleClose(item, index)"
            @contextmenu.prevent="openContextMenu(index, $event)"
            ><div>{{ item.name }}</div>
          </el-tag>
        </div>
      </el-scrollbar>
    </el-card>
  </div>
  <div>
    <ul v-show="visible" :style="{ left: tagCl.left + 'px', top: tagCl.top + 'px' }" class="tags-view__menu">
      <li @click="refreshSelectedTag(tagCl.selectedTag)">
        <el-icon>
          <RefreshRight />
        </el-icon>
        刷新
      </li>
      <li v-if="!isAffix()" @click="closeSelectedTag(tagCl.selectedTag)">
        <el-icon>
          <CircleClose />
        </el-icon>
        关闭
      </li>
      <li @click="closeOtherTags(tagCl.selectedTag)">
        <el-icon>
          <CircleCloseFilled />
        </el-icon>
        关闭其它
      </li>
      <li v-if="!isFirstView(tagCl.selectedTag)" @click="closeLeftTags(tagCl.selectedTag)">
        <el-icon><Back /></el-icon>
        关闭左侧
      </li>
      <li v-if="!isLastView(tagCl.selectedTag)" @click="closeRightTags(tagCl.selectedTag)">
        <el-icon><Right /></el-icon>
        关闭右侧
      </li>
      <li @click="closeAllTags">
        <el-icon>
          <CircleClose />
        </el-icon>
        关闭所有
      </li>
    </ul>
  </div>
</template>
<script lang="ts" setup>
import { tagClass } from '@/page/types/admin/tags'
import router from '@/router/router'
import { ComponentInternalInstance } from 'vue'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
const tagCl = reactive(new tagClass())
const visible = ref(false)
watch(visible, value => {
  if (value) {
    document.body.addEventListener('click', closeMenu)
  } else {
    document.body.removeEventListener('click', closeMenu)
  }
})
function closeMenu() {
  visible.value = false
}

//关闭标签
const handleClose = (tag: any, index: number) => {
  const routers = tagCl.tagsStore.menuTags
  const length = routers.length - 1
  tagCl.tagsStore.remove(tag)
  if (length === 0) {
    router.push({ path: '/system/frist/frist' })
    return
  }
  // 如果关闭的标签不是当前路由的话，就不跳转
  if (tag.path !== router.currentRoute.value.path) {
    return
  }
  switch (index) {
    case length:
      //vuex调方法的另一种写法
      router.push({ path: routers[index - 1].path })
      break
    default:
      router.push({ path: routers[index].path })
  }
}
const handleClick = (item: any) => {
  router.push({ path: item.path })
}
const openContextMenu = (index: number, e: MouseEvent) => {
  if (index === 0) {
    return
  }
  const menuMinWidth = 105
  const offsetWidth = proxy?.$el.offsetWidth // container width
  const maxLeft = offsetWidth - menuMinWidth // left boundary
  const l = e.clientX - 20 + 15 // 15: margin right
  if (l > maxLeft) {
    tagCl.left = maxLeft
  } else {
    tagCl.left = l
  }
  tagCl.top = e.clientY
  visible.value = true
  tagCl.selectedTag = index
}
const isFirstView = (index: number) => {
  return index == 1
}
const isLastView = (index: number) => {
  return tagCl.tagsStore.menuTags.length - 1 == index
}
const closeSelectedTag = (index: number) => {
  handleClose(tagCl.tagsStore.menuTags[index], index)
}
const closeAllTags = () => {
  tagCl.tagsStore.removeAll()
  router.push({ path: '/system/frist/frist' })
}
const refreshSelectedTag = (index: number) => {
  const data = tagCl.tagsStore.menuTags[index]
  tagCl.tagsStore.remove(data)
  tagCl.tagsStore.setTags(data)
  router.push({ path: data.path })
}
const isAffix = () => {}
const closeOtherTags = (index: number) => {
  const data = tagCl.tagsStore.menuTags[index]
  tagCl.tagsStore.removeAll()
  tagCl.tagsStore.setTags(data)
}
const closeLeftTags = (index: number) => {
  const bach = [] as any[]
  for (let i = 1; i < index; i++) {
    bach.push(tagCl.tagsStore.menuTags[i])
  }
  tagCl.tagsStore.batchRemove(bach)
}
const closeRightTags = (index: number) => {
  const bach = [] as any[]
  for (let i = index + 1; i <= tagCl.tagsStore.menuTags.length; i++) {
    bach.push(tagCl.tagsStore.menuTags[i])
  }
  tagCl.tagsStore.batchRemove(bach)
}
</script>
<style lang="scss" scoped>
.el-tabs--card {
  height: 10px;
}

.el-tab-pane {
  height: 10px;
}

.el-card {
  height: 30px;
  --el-card-padding: 5px;
}

.el-card__body {
  height: 30px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.el-tag {
  cursor: pointer;
  align-items: center;
  margin-top: 1px;
  padding-top: 0px;
  margin-left: 2px;
  margin-right: 2px;
  border-radius: 0px;
}

.tags-view__menu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);

  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;

    &:hover {
      background: #eee;
    }
  }
}

.scrollbar-flex-content {
  display: flex;
}
.scrollbar-demo-item {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-radius: 4px;
}
.el-select {
  width: 200px;
}
</style>
